<?php
/*=============================================================================
|| ##################################################################
||	phpFoX Konsort
|| ##################################################################
||
||	Copyright		: (C) 2005-2007 PHPFOX Limited a Reality Fox Creation
||	Contact			: info@phpfox.com
||
||	- phpFoX and all of its source code and files are protected by Copyright Laws.
||
||	- The license for phpFoX permits you to install this software on a single domain (.com, .org, .net, etc.).
||
||	- You may also not remove this copyright screen which shows the copyright information and credits for phpFoX (RealityFOX Creations).
||
||	- phpFoX Konsort is NOT a FREE software - http://www.phpfox.com/license/
||
|| ##################################################################
=============================================================================*/

/* $File: ./include/modules/Messenger/classes/PhpFox_ServiceMessenger.class.php, $Author:  $ */



/** Service for working with messages functionality (all types)
 *
 * @package module.messenger
 * @version $Id:
 *   PHPFox Team ()
 */
class PhpFox_Mod_Messenger_ServiceMessenger extends BaseService
{
    /** List users messages (inbox, sentbox)
     *
     * @param  array  $aCond     condition array
     * @param  int    $iPage	 page number
     * @param  int	  $iPageSize page size (row per page)
     * @param  string $sOrder	 order string
     * @return array  $aRes  	 Result
     */
    function &listMessages($aCond = array(), $iPage=0, $iPageSize=0, $sOrder = '')
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');

        $aRes = $oMesseng->getList($aCond, $iPage, $iPageSize, $sOrder);
        return $aRes;
    }

    function listAlerts($iUser_id, $iPage=0, $iPageSize=0, $sOrder = '')
    {
        $iTotal = $this->oDatabase->getRow("
        	SELECT 
        		COUNT(*) AS count 
        	FROM ". App::getT('mail_alert') ." AS a
        		JOIN ". App::getT('comments') ." AS c ON(a.c_id = c.cid)
        		LEFT JOIN ". App::getT('videos_comments') ." AS v ON(a.c_id = v.cm_id)
        	WHERE a.to_id = '". $iUser_id ."'
       	");

        $iOffset = $this->oDatabase->_getPageNum($iPage, $iPageSize, $iTotal['count']);

        $aQuery = $this->oDatabase->getRows("
        	SELECT 
        		a.id, a.type, a.item, a.time, a.user_id, a.seen, u.user, IF(a.type != 6, c.text, v.cm_text) AS text
        	FROM ". App::getT('mail_alert') ." AS a
        		JOIN ". App::getT('user') ." AS u ON(a.user_id = u.id)
        		JOIN ". App::getT('comments') ." AS c ON(a.c_id = c.cid)
        		LEFT JOIN ". App::getT('videos_comments') ." AS v ON(a.c_id = v.cm_id)
        	WHERE a.to_id = '". $iUser_id ."'        	
        	". ($sOrder ? " ORDER BY ". $sOrder ." " : "") ."        	
        	". ($iPageSize ? " LIMIT ". $iOffset .",". $iPageSize ." " : "") ."        	
        	");

        return array($aQuery, $iTotal['count']);
    }

    function deleteAlert($iId)
    {
    	$this->oDatabase->_delete(App::getT('mail_alert'), " id = '". $iId ."' AND to_id = '". App::getUser('id') ."' ");
    	return true;
    }

    function getAlertView($iId, $sUrl = "")
    {
    	$aItem = $this->oDatabase->getRow("SELECT a.id, a.type, a.item, a.seen, a.c_id, a.time, IF(a.type != 6, c.text, v.cm_text) AS text, u.user FROM
    		". App::getT('mail_alert') ." AS a
    			LEFT JOIN ". App::getT('comments') ." AS c ON(a.c_id = c.cid)
    			LEFT JOIN ". App::getT('user') ." AS u ON(a.user_id = u.id)
    			LEFT JOIN ". App::getT('videos_comments') ." AS v ON(a.c_id = v.cm_id)
    		WHERE a.id = '". $iId ."'
    	");

		if ( $aItem['seen'] != '1' )
		{
			$this->oDatabase->update(App::getT('mail_alert'), array('seen' => '1'), " id = '". $aItem['id'] ."' ");
		}

		return $aItem;
	}

    function getAlert($iId, $sUrl = "", $sUser = "", $bIsQuote = false)
    {
    	$aItem = $this->oDatabase->getRow("
    		SELECT 
    			a.id, a.type, a.item, a.seen, u.user, IF(a.type != 6, c.cid, v.cm_id) AS main_id
    		FROM ". App::getT('mail_alert') ." AS a
    			LEFT JOIN ". App::getT('user') ." AS u ON(a.item = u.id)
    			LEFT JOIN ". App::getT('comments') ." AS c ON(a.c_id = c.cid)
    			LEFT JOIN ". App::getT('videos_comments') ." AS v ON(a.c_id = v.cm_id)
    		WHERE a.id = '". $iId ."'
    	");

		if ( !isset($aItem['id']) )
		{
			return;
		}

		switch($aItem['type'])
		{
		 	 case '1':
		 	 $sUrl = App::makeUrl('public.blog.view', array('id' => $aItem['item'], 'quote' => ($bIsQuote ? $aItem['main_id'] : '')));
		 	 break;
		 	 case '2':
		 	 $sUrl = App::makeUrl('public.user.guestbook.quote_' . $aItem['main_id'], array('name' => ($sUser ? $sUser : $aItem['user'])));
		 	 break;
		 	 case '3':
		 	 $sUrl = App::makeUrl('public.gallery.view', array('id' => $aItem['item'], 'quote' => ($bIsQuote ? $aItem['main_id'] : '')));
		 	 break;
		 	 case '4':
		 	 $sUrl = App::makeUrl('public.music.song', array('id' => $aItem['item'], 'quote' => ($bIsQuote ? $aItem['main_id'] : '')));
		 	 break;
		 	 case '5':
		 	 $sUrl = App::makeUrl('public.music.album', array('id' => $aItem['item'], 'quote' => ($bIsQuote ? $aItem['main_id'] : '')));
		 	 break;
		 	 case '6':
		 	 $sUrl = App::makeUrl('public.videos', array('id' => $aItem['item'], 'quote' => ($bIsQuote ? $aItem['main_id'] : '')));
		 	 break;
		}
	
		if ( empty($sUrl) )
		{
			return;
		}

		if ( $aItem['seen'] != '1' )
		{
			$this->oDatabase->update(App::getT('mail_alert'), array('seen' => '1'), " id = '". $aItem['id'] ."' ");
		}

    	return $sUrl;
    }

    /** Get message by Id
     *
     * @param 	int		$iMessageId
     * @return 	array 	Message details
     */
    function getMessage($iMessageId, $bIsInBox = true)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $sApend = (!$bIsInBox) ? ' AND is_del_sent = 1' : '';

        $sSql = 'SELECT * FROM '.$oMesseng->sTable.' WHERE id = '.$iMessageId.$sApend;

        return $oMesseng->oDb->getRow($sSql);
    }
    /**
     * Calculate pager (next, preview message)
     *
     * @param integer $iMessageId
     * @param string $sUser (User name)
     * @param string $sType (mail or crush)
     * @param boolean $bIsInbox (inbox or sentbox)
     * @return array (result 0=>preview 1=> next)
     */
    function getAllMessages($iMessageId, $sUser, $sType = 'mail', $bIsInbox=true)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $sApend = ($bIsInbox) ? ' AND `to` = "'.$sUser.'"' : ' AND `from` = "'.$sUser.'" AND is_del_sent = 0';
        $iPrev = $oMesseng->oDb->getField('SELECT `id` FROM '.$oMesseng->sTable.' WHERE type ="'.$sType.'" AND id < '.$iMessageId.$sApend.' ORDER BY `id` DESC LIMIT 1');
        $iNext = $oMesseng->oDb->getField('SELECT `id` FROM '.$oMesseng->sTable.' WHERE type ="'.$sType.'" AND id > '.$iMessageId.$sApend.' ORDER BY `id` ASC LIMIT 1');
        return array($iPrev, $iNext);
    }
    /** Send message and notification (all types, e.g. crush,comment,mail)
     *
     * @param 	array 	$aData 		message details (titles, to, text)
     * @param 	string 	$sSender	sender name
     * @param 	string 	$sType 		mail, crush, comment
     * @param 	bool	$sSendEmail	option to send an email notice
     * @return  bool	true-complited, false-errors
     */
    function sendMessage($aData, $sSender, $sType='mail', $bSendEmail = true)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $sUserMail = $this->_checkRecipent($aData['to']);
        $oSrvAccount = App::getModuleService('Account', 'Account');
        $oUser = $oSrvAccount->getByUsername($aData['to']);
        $bNotifMail = ($oUser->aData['not_2'] == 0) ? false : true;
        $bNotifCrash = ($oUser->aData['not_3'] == 0) ? false : true;

        if(empty($sUserMail))
        {
            $this->addErrors(App::format('Mod_Messenger.member.notexists'));
            return false;
        }
        switch ($sType)
        {
			case 'crush':
				$aVars	 = array(
			        				'SITENAME'    => App::getSetting('site_name'),
			        				'TO'		  => $aData['to'],
			        				'CRUSHINBOX'  => App::makeUrl('public.account.messages.crush').'box_inbox/',
        						);
        		$sMailTitle = App::format('core.crush.alert');
				$sMailTemplate = 'email_crush';
			    break;

			default:
			    $aVars	 = array(
			        				'SITENAME'    => App::getSetting('site_name'),
			        				'TO'		  => $aData['to'],
			        				'FROM'		  => $sSender,
			        				'INBOXLINK'   => App::makeUrl('public.account.messages'),
        						);
				$sMailTitle = App::format('core.email.message');
			    $sMailTemplate = 'email_newmail';
				break;
		}

		$aData['seen'] = (isset($aData['seen']) ? $aData['seen'] : '');
        $sSql = 'INSERT INTO '.App::getT('mail').' (`to`,`from`,`title`,`text`,`time`,`seen`,`type`,`ip`)
				 VALUES ("'.$aData['to'].'","'.$sSender.'","'.mysql_escape_string($aData['title']).'","'.mysql_escape_string($aData['text']).'",'.time().',"'.$aData['seen'].'","'.$sType.'","")';
        $oMesseng->oDb->query($sSql);
		
        if ($bSendEmail)
        {
        	$oMailer = &App::newObject('mail_Mailer');
        	if($sType == 'crush' && $bNotifCrash)
        	{
		  		$oMailer->send($sMailTemplate, $sUserMail, $sMailTitle, $aVars);
        	}
			if($sType == 'mail' && $bNotifMail)
			{
		  		$oMailer->send($sMailTemplate, $sUserMail, $sMailTitle, $aVars);
			}
        }
        return true;
    }
    /** Check user name
     *
     * @access 	private
     * @param 	string 	$sName user name
     * @return 	string  if name not exists return empty string
     */
    function _checkRecipent($sName)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');

        $sSql = 'SELECT email FROM '.App::getT('user').' WHERE user = "'.$sName.'"';
        return $oMesseng->oDb->getField($sSql);
    }
    /** Delete user messages
     *
     * @param 	mixed $mAccIds id(s) message(s)
     * @return 	bool
     */
    function delItems($mAccIds)
    {
        if (!is_array($mAccIds))
        {
            $mAccIds = array($mAccIds);
        }
        $oMesseng = $this->_oModule->getItem('Messenger');
        if ($mAccIds)
        {
            $oMesseng->delete($mAccIds);
            return true;
        }
    }
    /** Set message status
     *
     * @param int    $iMessageId
     * @param string $sStatus (empty - not seen or new, 2 - viewed or not guessed, 3 - guessed)
     */
    function setViewedStatus ($iMessageId, $sStatus = '')
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $oMesseng->aData['seen'] 	= $sStatus;
        $oMesseng->aData['id'] 		= $iMessageId;
        $oMesseng->update();
    }
    /** Emulate on delete message (sentbox)
     *
     * @param mixed $mMessageId (array or int Message Id)
     */
    function markDel($mMessageId,$iUserID)
    {	error_reporting(E_ALL);
        $oMesseng = &$this->_oModule->getItem('Messenger');

        if(!is_array($mMessageId))
            $mMessageId = array($mMessageId);

        foreach ($mMessageId as $i=>$iId)
        {
        $sSql = 'SELECT is_del_sent
				 FROM '.App::getT('mail').'
				 WHERE id = '.$iId.'';
       
        $flag=$oMesseng->oDb->getField($sSql);
        	if($flag==0)
        	{
	            $oMesseng->aData['id']      = $iId;
	            $oMesseng->aData['is_del_sent'] = $iUserID;
	            $oMesseng->update();
        	}
        	else 
        	{
        		$this->delItems($iId);
        	}
        }
    }
    /** Check Guess for crush alert
     *
     * @param 	string 	$sName 		user name
     * @param 	int	 	$iCrushId
     * @return 	bool
     */
    function checkGuess($sName, $iCrushId)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $sSql = 'SELECT COUNT(*)
				 FROM '.App::getT('mail').'
				 WHERE id = '.$iCrushId.' AND `from` = "'.$sName.'"';

        return $oMesseng->oDb->getField($sSql) ? true : false;
    }
    /** Get Users Freiend hash
     *
     * @param 	string $sUser user name
     * @return  array
     */
    function getFriendsToSelect($sUser)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');

        $sSql = 'SELECT id,buddy
				 FROM '.App::getT('buddy').'
				 WHERE user = "'.$sUser.'"';

        return $oMesseng->oDb->getHash($sSql);
    }
    /** List crush alerts for admin panel
     *
     * @param 	array  $aCond     condition array
     * @param 	int    $iPage	  page number
     * @param 	int	   $iPageSize page size (row per page)
     * @param 	string $sOrder	  order string
     * @return 	array  $aRes  	  Result
     */
    function getAlertList($aCond = array(), $iPage=0, $iPageSize=0, $sOrder = '')
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');

        $aRes = $oMesseng->getList($aCond, $iPage, $iPageSize, $sOrder);

        return $aRes;
    }
    /** List messages for admin panel
     *
     * @param 	array  $aCond     condition array
     * @param 	int    $iPage	  page number
     * @param 	int	   $iPageSize page size (row per page)
     * @param 	string $sOrder	  order string
     * @return 	array  $aRes  	  Result
     */
    function getMessageList($aCond = array(), $iPage=0, $iPageSize=0, $sOrder = '')
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');

        $aRes = $oMesseng->getList($aCond, $iPage, $iPageSize, $sOrder);

        return $aRes;
    }
    /** List membership to select (drop-down)
     *
     * @return array Membersship hash
     */
    function getShipToSelect()
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');

        $sSql = 'SELECT membership_id, title FROM '.App::getT('membership');

        return $oMesseng->oDb->getHash($sSql);
    }
    /** Send Mass Email
     *
     * @param  array $aData Message data
     * @return bool
     */
    function sendMassMail($aData, $iCurPage = 1)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $sCond = '';
        $aData['subject'] = $oMesseng->oDb->escape($aData['title']);

        if($aData['to'] !== 'none' && $aData['to'] !== 'all')
        {
            $sCond .= 'AND type = '.intval($aData['to']);
        }
        
        if(!empty($aData['user']))
        {
            preg_match_all('/([^;|,|\s]+)/i', $aData['user'], $aMatch);
            $sOp = (!empty($sCond)) ? ' OR' : ' AND';
            foreach ($aMatch[1] as $i=>$sUser)
            {
                if(!$this->_checkRecipent($sUser))
                {
                    unset($aMatch[1][$i]);
                    if($aData['to'] == 'none')
                        $this->addErrors(App::format('Mod_Messenger.member.notexists'));
                }
            }
            $sCond .= $sOp.' user IN("'.join('","', $aMatch[1]).'")';
        }

        $iCntTot = $oMesseng->oDb->getField('SELECT COUNT(*) FROM '.App::getT('user').' WHERE is_banned != "1" '.$sCond);

        $iSize   = !empty($aData['total']) ? intval($aData['total']) : 0;
        $iFrom   = ($iCurPage == 1) ? 0 : ($iSize*$iCurPage)-$iSize;

        $iTo = ($iCntTot < ($iSize*$iCurPage)) ? $iCntTot : $iSize*$iCurPage;

        $sLimit = ($iTo) ? ' LIMIT '.$iFrom.','.$iSize : '';

        $sSql = 'SELECT email, `user` FROM '.App::getT('user').' WHERE is_banned != "1" '.$sCond.$sLimit;

        $aRes = $oMesseng->oDb->getRows($sSql);

        $aAdMail = array
        (
        	'subject' => $aData['title'],
        	'text' => $aData['text'],
        	'time' => time()
        );
        $oMesseng->oDb->insert(App::getT('admin_mass_mail'), $aAdMail);
        
        // send mail
        $oMailer = &App::newObject('mail_Mailer');

        foreach ($aRes as $i => $aEmail)
        {
            $aVars = array
            (
                'CONTENT'  => str_replace('{%USERNAME%}', $aEmail['user'], $aData['text']),
                'USERNAME' => '',
                'IMG'      => '',
            );
			$sMailTitle = $aData['title'];
		    $sMailTemplate = 'email_blank';

		    $oMailer->send($sMailTemplate, $aEmail['email'], $sMailTitle, $aVars);
        }

        return array($iCntTot, $iFrom, $iTo);
    }


    /**
     * Check new messages in member panel
     *
     * @param string $sUser
     * @return array (Result Hash)
     */
    function checkNewMessages($sUser)
    {
        $aRes['iMail']  = $this->oDatabase->getField('SELECT COUNT(*) FROM '.App::getT('mail').' WHERE type = "mail" AND `to` ="'.$sUser.'" AND seen = ""');
        $aRes['iCrush'] = $this->oDatabase->getField('SELECT COUNT(*) FROM '.App::getT('mail').' WHERE type = "crush" AND `to` ="'.$sUser.'" AND seen = ""');
		$aRes['iFriend']= $this->oDatabase->getField('
        	SELECT COUNT(*) 
        	FROM '.App::getT('buddy_add').' AS b 
        		JOIN ' . App::getT('user') . ' AS u 
        			ON (b.user = u.user)
        	WHERE b.friend = "'.$sUser.'"
        ');
        $aRes['iAlert']= $this->oDatabase->getField('
        	SELECT COUNT(*) 
        	FROM ' . App::getT('mail_alert') . ' AS a
        		JOIN ' . App::getT('user') . ' AS u ON(a.user_id = u.id)
        		JOIN ' . App::getT('comments') . ' AS c ON(a.c_id = c.cid) 
        	WHERE a.to_id = "'. App::getUser('id') .'" AND a.seen != "1"
        	');

        $iTotalMessages = ($aRes['iMail'] + $aRes['iCrush'] + $aRes['iFriend'] + $aRes['iAlert']);

        return array($aRes,$iTotalMessages);
    }

    function addMailAlert($aVar)
    {
    	$aQuery = array
    	(
    		'type' => $aVar['type'],
    		'item' => $aVar['item'],
    		'c_id' => $aVar['c_id'],
    		'to_id' => $aVar['to_id'],
    		'user_id' => App::getUser('id'),
    		'time' => time(),
    	);
    	$this->oDatabase->insert(App::getT('mail_alert'), $aQuery);

    	return true;
    }


    /**
     * Check user inbox limit
     *
     * @param string $sUser (User name)
     * @param array $aMemberShip (Membership details)
     * @param string $sType (owner or recipient)
     * @return boolean
     */
    function checkInboxLimit($sUser, $aMemberShip, $sType = 'owner')
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $oAccServ = &App::getModuleService('Account', 'Security');
        $nUser=$oAccServ->getUserByName($sUser);
        $iCurentMail = $oMesseng->oDb->getField('SELECT COUNT(id) FROM '.App::getT('mail').' WHERE type = "mail" AND `to` ="'.$sUser.'" AND is_del_sent!="'.$nUser->aData['id'].'"');
 
        if((0 !=$aMemberShip['max_inbox']) && $iCurentMail >= $aMemberShip['max_inbox'])
        {
            $sType == 'owner' ? $this->addErrors(App::format('Mod_Messenger.inbox.limit')) : $this->addErrors(App::format('Mod_Messenger.error.limit'));
            return false;
        }
        return true;
    }
    /**
     * Send User Report
     *
     * @param array $aData (Report data)
     * @param string $sSender (Sender name)
     * @return boolean
     */
    function sendReport($aData, $sSender)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $oMailer = &App::newObject('mail_Mailer');
        App::loadClass('Text');
        $oTxt = new Text();
        $aVars = array(
                            'REPORTER'=> $sSender,
                            'SITELINK'=> App::getParam('url'),
                            'MESSAGE' => $oTxt->parseText($aData['text']),
                            'USER'    => $aData['user'],
                            'SITENAME'=> App::getSetting('site_name'),
                            );
        $sMailTitle = App::format('Mod_Messenger.report_user');
	    $sMailTemplate = 'email_report';
	    $aEmail = explode(',',App::getSetting('contact_us_emails'));
	    $sEmail = join(', ', array_values($aEmail));
        if(!empty($sEmail))
        {
            $oMailer->send($sMailTemplate, $sEmail, $sMailTitle, $aVars);
		}
        return true;
    }
    /**
     * Check new message in user inbox (ajax - implantation)
     *
     * @param string $sUser
     * @return int - number of new messages
     */
    function checkUserMessage($sUser)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        return $oMesseng->oDb->getField('SELECT COUNT(*) FROM '.App::getT('mail').' WHERE type = "mail" AND `to` ="'.$sUser.'" AND seen = ""');
    }
    /**
     * Callback delete all user messages
     *
     * @param mixed $mParam
     * @return boolean
     */
    function _callbackDeleteUser($mParam)
    {
        $oMesseng = &$this->_oModule->getItem('Messenger');
        $aAccountHash = $mParam['aIds'];
        $oAccServ = &App::getModuleService('Account', 'Account');

        foreach ($aAccountHash as $iUserId)
        {
            $oAcc = $oAccServ->getById($iUserId);
            $sUser = $oAcc->aData['user'];
            $aMessage = $oMesseng->oDb->getHash('SELECT `id` AS a, `id` AS b FROM '.$oMesseng->sTable.' WHERE `to` = "'.$sUser.'" OR `from` = "'.$sUser.'"');
            if(!empty($aMessage))
                $oMesseng->delete($aMessage);
            // clean shoutbox & livechat
            $oMesseng->_initTable('chat');
            $oMesseng->oDb->query('DELETE FROM '.$oMesseng->sTable.' WHERE `user` = "'.$sUser.'"');
        }
        return true;
    }
    /**
     * Callback onCreate account. Create Welcome message
     *
     * @param array $aParams
     * @return boolean
     */
    function onCreateAccount($aParams)
    {
        if($sNewFriend = App::getSetting('new_friend'))
        {
            $oMessage = $this->_oModule->getService('Messenger');
            $oLang = &App::getLanguage();
            $sTplFile = $oLang->getContent('welcome_note');
           	$subject = array();
			if (eregi("<subject>",$sTplFile))
			{
				$sub = explode("<subject>",$sTplFile);
				$subject = explode("</subject>",$sub[1]);
			}
			$message = preg_replace("/\<subject>(.*?)\<\/subject>/si","",$sTplFile);
            $aInfo = array('to'=> $aParams['Account']->aData['user'], 'title'=>$subject[0], 'text'=> $message, 'seen' => "");
            $oMessage->sendMessage($aInfo, $sNewFriend, 'mail', false);
        }

        return true;
    }
}
?>